namespace Core.Features
{
    using System;
    using Base;
    using Contracts.Enums;
    using Resources;
    using System.Linq;
    using Contracts.Interfaces;

    
    public sealed class TopSpeed<T> : FeatureBase<object>
    {
        public TopSpeed(){}

        public TopSpeed(T value) 
            : base(value){ }
        /// <summary>
        /// Obtains the feature name
        /// </summary>
        public override string Name
        {
            get { return "Top speed"; }
        }
        /// <summary>
        /// Obtains the feature group
        /// </summary>
        public override FeatureGroupsEnum FeatureGroup{ get { return FeatureGroupsEnum.General; } }
        /// <summary>
        /// Obtains the feature type
        /// </summary>
        public override FeaturesEnum FeatureType { get { return FeaturesEnum.TopSpeed; } }
        /// <summary>
        /// Obtains or defines the feature unit
        /// </summary>
        public override string Unit { get { return Traduction.label_unit_speed; } }

        public override bool IsRounded
        {
            get { return false; }
        }

        public override void SetModifiedValue(IAgent agent, IRobot robot)
        {
            if (agent == null || robot == null) return;
            /*
                Bot Speed :
                N = Navigation extension level
                NM = Navigation extension modifier value
                BM = Base robot mass
                M = Module mass
                LWF = Bonus from lightweight frame
                BBS = Base bot speed
                RBTM = Robot Mass
                SPD = Speed
             
                RBTM = BM + SUM(M) - (LWF * BM)
                SPD = (BM / RBTM) * (1 + (N * NM)) * BBS
             */

            
            
            double baseMass = (double)robot.Features.Where(f => f.FeatureType == FeaturesEnum.RobotMass).FirstOrDefault().Value;
            double modMass = (double)robot.Features.Where(f => f.FeatureType == FeaturesEnum.RobotMass).FirstOrDefault().ModifiedValue;
            double baseSpeed = (double)robot.Features.Where(f => f.FeatureType == this.FeatureType).FirstOrDefault().Value;

            // nexus Bonus
            double nexusBonus = robot.Modules.SumModifiersValues(FeatureTypesEnum.Robot, this.FeatureType, ModuleGroupsEnum.NexusModuleVelocity);
            double nexusSkillBonus = agent.Extensions.SumModifiersValues(FeatureTypesEnum.Module, this.FeatureType);

            double nexusTotalBonus = 0;

            if (nexusBonus != 0)

                nexusTotalBonus = nexusBonus + (((1 + nexusBonus) * nexusSkillBonus) / 100);


            double speed = (baseMass / modMass) * baseSpeed * (1 + nexusTotalBonus);


            ModifiedValue = IsRounded 
                ? Math.Round(speed,0,MidpointRounding.AwayFromZero)
                : Math.Round(speed,2);
        }
        
    }
}